﻿namespace GreenIsomer.Data.Entities.Ddl {
	using System;
	using System.Collections.Generic;
	using System.Globalization;

	public class TableColumn {

		public TableColumn() { }

		public string Name { get; set; }

		public string DataType { get; set; }

		public string OriginalDataType { get; set; }

		public short? Size { get; set; }

		public byte? Scale { get; set; }

		public byte? Precision { get; set; }

		public bool IsNullable { get; set; }

		public DefaultValue DefaultValue { get; set; }

		public virtual void WriteScript(DdlWriter writer) {

			writer.StartNewLine();

			writer.WriteScript("\"");
			writer.WriteScript(Name);
			writer.WriteScript("\"");

			writer.AddSpace();

			writer.WriteScript(DataType);

			if(Size.HasValue) {
				writer.WriteScript("(");
				writer.WriteScript(Size.Value.ToString(CultureInfo.InvariantCulture));
				writer.WriteScript(")");
			} else if(Scale.HasValue || Precision.HasValue) {
				writer.WriteScript("(");
				writer.WriteScript((Scale ?? Precision.Value).ToString(CultureInfo.InvariantCulture));
				writer.WriteScript(",");
				writer.WriteScript((Precision ?? 0).ToString(CultureInfo.InvariantCulture));
				writer.WriteScript(")");
			}

			writer.AddSpace();

			writer.WriteScript(IsNullable ? "NULL" : "NOT NULL");

			writer.AddSpace();

			if(DefaultValue != null) DefaultValue.WriteScript(writer);

		}

		public virtual void ReplaceDataType(IEnumerable<TypeConversion> typeConversions) {
			if(typeConversions == null) throw new ArgumentNullException("typeConversions");

			if(string.IsNullOrEmpty(DataType)) return;
			string dataType = DataType.ToUpperInvariant();
			string originalDataType = (OriginalDataType ?? string.Empty).ToUpperInvariant();

			foreach(TypeConversion typeConversion in typeConversions) {
				string ssdlType = typeConversion.SsdlType;
				if(string.IsNullOrEmpty(ssdlType)) continue;

				if(ssdlType.ToUpperInvariant() != dataType) continue;

				string originalSsdlType = typeConversion.OriginalSsdlType;
				if(!string.IsNullOrEmpty(originalSsdlType) && originalSsdlType.ToUpperInvariant() != originalDataType) continue;

				DataType = typeConversion.DatabaseType;
				Size = typeConversion.DatabaseSize;
				Scale = typeConversion.DatabaseScale;
				Precision = typeConversion.DatabasePrecision;

				return;
			}
		}

	}

}